#include "mainwidget.h"
#include "sessionlist.h"
#include "debug.h"

//----------------------------------------------------------------------------------------------------------------------------------
/// 懒汉单例模式
//----------------------------------------------------------------------------------------------------------------------------------


// 初始化单例对象--懒汉模式
MainWidget* MainWidget::istance = nullptr;

// 获取单例对象
// 这里不需要考虑线程安全问题，主窗口在程序启动的时候就进行了创建实例对象，那个时候还不存在多个线程呢
// 后续在使用单例对象的时候，使用的一定是创建好的了，所以不存在线程安全问题
MainWidget *MainWidget::GetInstance()
{
    // 如果没有单例对象的化，就创建一个
    if(istance == nullptr)
    {
        // 此处不传入参数的化，就代表以桌面作为父窗口
        // 因为此处的窗口为程序的主窗口，所以他也就没有父窗口了。
        istance = new MainWidget();
    }
    return istance;
}

//----------------------------------------------------------------------------------------------------------------------------------
/// 构造函数
//----------------------------------------------------------------------------------------------------------------------------------

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    // 设置窗口标题与图标
    this->setWindowTitle("MyWeChat");
    this->setWindowIcon(QIcon(":/image/windows_icon.png"));

    // 初始化整个主窗口的样式布局
    InitMainWindow();
    // 初始化左侧局部窗口
    InitLeftWindow();
    // 初始化中间局部窗口
    InitMidWindow();
    // 初始化右侧局部窗口
    InitRightWindow();
    // 初始化信号槽
    InitSignalSlot();
}
//析构函数
MainWidget::~MainWidget() {}

//----------------------------------------------------------------------------------------------------------------------------------
/// 初始化整个主窗口的样式布局
//----------------------------------------------------------------------------------------------------------------------------------

void MainWidget::InitMainWindow()
{
    // 水平布局管理器
    QHBoxLayout* layout = new QHBoxLayout();
    // 设置内部控件之间的间隔
    layout->setSpacing(0);
    // 设置内部的元素（控件）距离父窗口（主窗口）的距离
    layout->setContentsMargins(0, 0, 0, 0);
    this->setLayout(layout);

    // 不需要设置父窗口了，布局管理器会自动帮助我们设置
    left_window = new QWidget();
    mid_window = new QWidget();
    right_window = new QWidget();

    // 设置左侧和中间的宽度--不会随着窗口的改变而变化
    // 这里设计的大小是多少，起始不用我们程序员太关注，这部分工作属于每股人员进行设计的，到时候程序员根据设计稿进行编程就好
    left_window->setFixedWidth(50);
    mid_window->setFixedWidth(230);

    // 设置右侧的宽度--会随着窗口变化而适应，所以设置一个最小的宽度
    right_window->setMinimumWidth(500);

    // 设置整体窗口的最小长度
    this->setMinimumHeight(550);

    // 将子窗口部件添加到布局中
    layout->addWidget(left_window);
    layout->addWidget(mid_window);
    layout->addWidget(right_window);
}

//----------------------------------------------------------------------------------------------------------------------------------
/// 初始化左侧局部窗口
//----------------------------------------------------------------------------------------------------------------------------------

void MainWidget::InitLeftWindow()
{
    // 设置背景颜色
    left_window->setStyleSheet("QWidget { background-color: #2E2E2E; }");

    // 垂直布局管理器
    QVBoxLayout* layout = new QVBoxLayout();
    left_window->setLayout(layout);
    // 设置内部的元素（控件）距离父窗口的距离
    layout->setContentsMargins(0, 20, 0, 0);
    // 设置元素之间的间距
    layout->setSpacing(5);

    // 用户头像
    userAvator = new QPushButton();
    // 设置按钮固定大小
    userAvator->setFixedSize(40, 40);
    // 设置头像按钮中的图片大小
    userAvator->setIconSize(QSize(40, 40));
    // 添加默认头像
    userAvator->setIcon(QIcon(":/image/people.png"));
    // 设置点击反馈的颜色为父元素的背景色，设置按钮悬停的颜色变化
    userAvator->setStyleSheet("QPushButton { background-color: transparent; border: none; }"
                                    "QPushButton:hover { background-color: transparent; border: none; }");
    // 将控件加入到布局管理器--水平方向居中，垂直靠上
    layout->addWidget(userAvator, 1, Qt::AlignTop | Qt::AlignHCenter);

    // 会话标签页按钮
    sessionTabButton = new QPushButton();
    sessionTabButton->setFixedSize(50, 50);
    sessionTabButton->setIconSize(QSize(50, 50));
    sessionTabButton->setIcon(QIcon(":/image/dialogue_true.png"));
    sessionTabButton->setStyleSheet("QPushButton { background-color: transparent; border: none; }"
                                    "QPushButton:hover { background-color: transparent; border: none; }");
    layout->addWidget(sessionTabButton, 1, Qt::AlignTop | Qt::AlignHCenter);

    // 好友标签页按钮
    friendTabButton = new QPushButton();
    friendTabButton->setFixedSize(50, 50);
    friendTabButton->setIconSize(QSize(50, 50));
    friendTabButton->setIcon(QIcon(":/image/friend.png"));
    friendTabButton->setStyleSheet("QPushButton { background-color: transparent; border: none; }"
                                    "QPushButton:hover { background-color: transparent; border: none; }");
    layout->addWidget(friendTabButton, 1, Qt::AlignTop | Qt::AlignHCenter);

    // 好友申请标签页按钮
    applyTabButton = new QPushButton();
    applyTabButton->setFixedSize(50, 50);
    applyTabButton->setIconSize(QSize(50, 50));
    applyTabButton->setIcon(QIcon(":/image/add_friend.png"));
    applyTabButton->setStyleSheet("QPushButton { background-color: transparent; border: none; }"
                                    "QPushButton:hover { background-color: transparent; border: none; }");
    layout->addWidget(applyTabButton, 1, Qt::AlignTop | Qt::AlignHCenter);

    //添加空白区域，让上面的控件靠上显示
    layout->addStretch(200);

}

//----------------------------------------------------------------------------------------------------------------------------------
/// 切换标签页按钮的信号槽绑定 与 槽函数实现
//----------------------------------------------------------------------------------------------------------------------------------

// 绑定信号槽
void MainWidget::InitSignalSlot()
{
    //-----------------------------------------------------------
    /// 连接信号槽--处理标签页的切换问题
    //-----------------------------------------------------------
    connect(sessionTabButton, &QPushButton::clicked, this, &MainWidget::switchTableToSession);
    connect(friendTabButton, &QPushButton::clicked, this, &MainWidget::switchTableToFriend);
    connect(applyTabButton, &QPushButton::clicked, this, &MainWidget::switchTableToApply);
}

// 切换到会话标签页槽函数
void MainWidget::switchTableToSession()
{
    // 切换标签页状态
    activeTab = ActiveTab::SESSION_TABLE;
    // 调整图标显示情况
    sessionTabButton->setIcon(QIcon(":/image/dialogue_true.png"));
    friendTabButton->setIcon(QIcon(":/image/friend.png"));
    applyTabButton->setIcon(QIcon(":/image/add_friend.png"));
    // 在主窗口中间部分加载出用户的会话列表数据
    this->LoadSessionList();
}
// 切换到好友标签页槽函数
void MainWidget::switchTableToFriend()
{
    // 切换标签页状态
    activeTab = ActiveTab::FRIEND_TABLE;
    // 调整图标显示情况
    sessionTabButton->setIcon(QIcon(":/image/dialogue.png"));
    friendTabButton->setIcon(QIcon(":/image/friend_true.png"));
    applyTabButton->setIcon(QIcon(":/image/add_friend.png"));
    // 在主窗口中间部分加载出用户的会话列表数据
    this->LoadSessionList();
}
// 切换到好友申请标签页槽函数
void MainWidget::switchTableToApply()
{
    // 切换标签页状态
    activeTab = ActiveTab::APPLY_TABLE;
    // 调整图标显示情况
    sessionTabButton->setIcon(QIcon(":/image/dialogue.png"));
    friendTabButton->setIcon(QIcon(":/image/friend.png"));
    applyTabButton->setIcon(QIcon(":/image/add_friend_true.png"));
    // 在主窗口中间部分加载出用户的会话列表数据
    this->LoadSessionList();
}


//----------------------------------------------------------------------------------------------------------------------------------
/// 初始化中间局部窗口
//----------------------------------------------------------------------------------------------------------------------------------

void MainWidget::InitMidWindow()
{
    // 设置颜色
    mid_window->setStyleSheet("QWidget { background-color: #FAF9F6; }");
    // 网格布局管理器
    QGridLayout* layout = new QGridLayout();
    mid_window->setLayout(layout);
    // 设置内部元素距离四周的距离
    layout->setContentsMargins(0, 20, 0, 0);
    // 设置内部元素之间的距离
    layout->setVerticalSpacing(10);
    layout->setHorizontalSpacing(0);

    // 添加搜素框
    searchEdit = new QLineEdit();
    // 固定高度
    searchEdit->setFixedHeight(30);
    // 设置提示字段
    searchEdit->setPlaceholderText("搜索");
    // 设置样式--设置搜索框圆角弧度
    searchEdit->setStyleSheet("QLineEdit { border-radius: 5px; background-color: #E2E2E2; }");

    // 添加按钮
    addFriendButton = new QPushButton();
    // 设置大小
    addFriendButton->setFixedSize(30, 30);
    // 添加图标--设置按钮颜色和弧度，以及按下和悬停的颜色
    addFriendButton->setIcon(QIcon(":/image/sub.png"));
    addFriendButton->setStyleSheet("QPushButton { border-radius: 5px; background-color: #E2E2E2; }"
                                   "QPushButton:hover { background-color: #D1D1D1; }");

    // 会话列表
    SessionList* sessionlist = new SessionList();

    // 为了更灵活的去只控制第一行的边距，不影响下方的会话列表，可以创建多个空白的控件添加到布局管理器当中
    QWidget* spacer1 = new QWidget();
    spacer1->setFixedWidth(10);
    QWidget* spacer2 = new QWidget();
    spacer2->setFixedWidth(10);
    QWidget* spacer3 = new QWidget();
    spacer3->setFixedWidth(10);

    // 将控件添加到布局管理器
    layout->addWidget(spacer1, 0, 0);
    layout->addWidget(searchEdit, 0, 1);
    layout->addWidget(spacer2, 0, 2);
    layout->addWidget(addFriendButton, 0, 3);
    layout->addWidget(spacer3, 0, 4);
    // 但是这样的话，我们的会话列表就会根第一行的第一个空白控件是一样的，但是我们设计的是想让会话列表沾满整个第二行
    // 所以要设置出现的位置，并设置占据横跨几行几列
    // 但是我们发现还不是我们最初设置的230px，这是因为他会受到系统缩放的影响，这个可以不在意，或者设置缩放为100%
    layout->addWidget(sessionlist, 1, 0, 1, 5);
}

//----------------------------------------------------------------------------------------------------------------------------------
/// 初始化右侧局部窗口
//----------------------------------------------------------------------------------------------------------------------------------

void MainWidget::InitRightWindow()
{
    // 设置背景颜色
    right_window->setStyleSheet("QWidget { background-color: #F5F5F5; }");

    // 整体（垂直）布局管理器
    QVBoxLayout* vlayout = new QVBoxLayout();
    right_window->setLayout(vlayout);
    // 设置距离
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setSpacing(0);
    vlayout->setAlignment(Qt::AlignTop);

    // 创建上方的标题栏
    QWidget* titleWidget = new QWidget();
    titleWidget->setFixedHeight(60);
    titleWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    titleWidget->setObjectName("titleWidget");
    titleWidget->setStyleSheet("#titleWidget { border-bottom: 1px solid #E7E7E7; border-left: 1px solid #D6D6D6; }");
    // 为标题栏添加控件--label和按钮
    // 水平布局管理器
    QHBoxLayout* hlayout = new QHBoxLayout();
    titleWidget->setLayout(hlayout);
    // 设置距离
    hlayout->setContentsMargins(20 ,0 ,10 ,0);
    hlayout->setSpacing(0);
    // 创建label控件
    QLabel* sessionTitleLabel = new QLabel();
    sessionTitleLabel->setStyleSheet("QLabel { font-size: 20px; color: black; border-bottom: 1px solid #E7E7E7; }");
#if TEST_UI
    sessionTitleLabel->setText("用户昵称/群聊名称");
#endif
    // 创建显示额外信息的按钮
    QPushButton* extraButton = new QPushButton();
    extraButton->setFixedSize(50, 50);
    extraButton->setIconSize(QSize(50, 50));
    extraButton->setIcon(QIcon(":/image/extra.png"));
    extraButton->setStyleSheet("QPushButton { border:none; }");
    // 将控件添加到标题栏的水平布局管理器
    hlayout->addWidget(sessionTitleLabel);
    hlayout->addWidget(extraButton);

    // 创建消息展示区
    messageShowArea = new MessageShowArea();
    // 创建消息编辑区
    messageEditArea = new MessageEditArea();

    // 添加到整体布局管理器
    vlayout->addWidget(titleWidget);
    vlayout->addWidget(messageShowArea);
    // 确保消息编辑区处于下方
    vlayout->addWidget(messageEditArea, 0, Qt::AlignBottom);
}


// 加载会话列表信息
void MainWidget::LoadSessionList()
{

}
